﻿using UnityEditor;
using UnityEngine;

namespace Core.Setting
{
    public partial class ScreenSetting
    {
        /// <summary>
        /// Unity Editor
        /// </summary>
        private class ScreenEditor : AbstractScreenPlatform
        {
            public override void Awake(ScreenSetting owner)
            {
                base.Awake(owner);

                Scrn.SafeArea = Screen.safeArea;

                Scrn.Size = new WH(Screen.width, Screen.height);
                var resolution = Screen.currentResolution;
                Scrn.Resolution = new WH(resolution.width, resolution.height);

                log.err(Scrn.SafeArea);
                log.err($"Screen.size={Scrn.Size} {Screen.currentResolution}");
                log.err($"Screen.orientation ={Screen.orientation}");

                //                Orientation = ScreenOrientation.Portrait;

                //                Screen.orientation = ScreenOrientation.Portrait;

                //                if (Screen.width > Screen.height)
                //                {
                //                    Screen.SetResolution(Screen.height, Screen.width, false);
                //                    Scrn.Listen();
                //#if UNITY_EDITOR
                //                    switchEditorViewOrientation();
                //#endif
                //                }
            }

            public override void Set(ESceneOrientation ori)
            {
                if (ori == ESceneOrientation.Portrait)
                {
                    if (IsLandscape())
                    {
                        Set(ScreenOrientation.Portrait);

                        Scrn.Listen();
                    }
                }
                else
                {
                    if (IsPortrait())
                    {
                        Set(ScreenOrientation.LandscapeLeft);

                        Scrn.Listen();
                    }
                }
            }

            private void Set(ScreenOrientation ori)
            {
                Screen.orientation = ori;
                Orientation = ori;

#if UNITY_EDITOR
                SwitchEditorViewOrientation();
#endif
            }

#if UNITY_EDITOR

            private static object gameViewSizesInstance;
            private static System.Reflection.MethodInfo getGroup;
            private static void SwitchEditorViewOrientation()
            {
                int width = Screen.height;
                int height = Screen.width;

                int index = FindSize(GetCurrentGroupType(), width, height);
                if (index == -1)
                {
                    //AddCustomSize(GameViewSizeType.FixedResolution, GetCurrentGroupType(), width, height, "");
                    //index = FindSize(GetCurrentGroupType(), width, height);
                    log.d("switchOrientation failed, can not find or add resoulution for " + width.ToString() + "*" + height.ToString());
                    return;
                }
                SetSize(index);
            }

            private static GameViewSizeGroupType GetCurrentGroupType()
            {
                var sizesType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes");
                var singleType = typeof(ScriptableSingleton<>).MakeGenericType(sizesType);
                var instanceProp = singleType.GetProperty("instance");
                getGroup = sizesType.GetMethod("GetGroup");
                gameViewSizesInstance = instanceProp.GetValue(null, null);

                var getCurrentGroupTypeProp = gameViewSizesInstance.GetType().GetProperty("currentGroupType");
                return (GameViewSizeGroupType)(int)getCurrentGroupTypeProp.GetValue(gameViewSizesInstance, null);
            }

            private static int FindSize(GameViewSizeGroupType sizeGroupType, int width, int height)
            {
                var group = GetGroup(sizeGroupType);
                var groupType = group.GetType();
                var getBuiltinCount = groupType.GetMethod("GetBuiltinCount");
                var getCustomCount = groupType.GetMethod("GetCustomCount");
                int sizesCount = (int)getBuiltinCount.Invoke(group, null) + (int)getCustomCount.Invoke(group, null);
                var getGameViewSize = groupType.GetMethod("GetGameViewSize");
                var gvsType = getGameViewSize.ReturnType;
                var widthProp = gvsType.GetProperty("width");
                var heightProp = gvsType.GetProperty("height");
                var indexValue = new object[1];
                for (int i = 0; i < sizesCount; i++)
                {
                    indexValue[0] = i;
                    var size = getGameViewSize.Invoke(group, indexValue);
                    int sizeWidth = (int)widthProp.GetValue(size, null);
                    int sizeHeight = (int)heightProp.GetValue(size, null);
                    if (sizeWidth == width && sizeHeight == height)
                        return i;
                }
                return -1;
            }

            private static object GetGroup(GameViewSizeGroupType type)
            {
                return getGroup.Invoke(gameViewSizesInstance, new object[] { (int)type });
            }

            public static void SetSize(int index)
            {
                var gvWndType = typeof(Editor).Assembly.GetType("UnityEditor.GameView");
                var selectedSizeIndexProp = gvWndType.GetProperty("selectedSizeIndex",
                        System.Reflection.BindingFlags.Instance |
                        System.Reflection.BindingFlags.Public |
                        System.Reflection.BindingFlags.NonPublic);
                var gvWnd = EditorWindow.GetWindow(gvWndType);
                selectedSizeIndexProp.SetValue(gvWnd, index, null);
            }
#endif
        }
    }
}
